package cn.pzx.base_module.base

import androidx.lifecycle.MutableLiveData
import androidx.lifecycle.ViewModel
import androidx.lifecycle.viewModelScope
import cn.pzx.base_module.http.BaseResult
import cn.pzx.base_module.http.ErrorResult
import cn.pzx.base_module.http.ErrorUtil
import com.blankj.utilcode.util.LogUtils
import kotlinx.coroutines.CoroutineScope
import kotlinx.coroutines.Dispatchers
import kotlinx.coroutines.launch
import kotlinx.coroutines.withContext

/**
 * @author pzx
 * @description:
 * @date :3/8/21 10:09 AM
 */
open class BaseViewModel : ViewModel() {

    var isShowLoading = MutableLiveData<Boolean>()//是否显示loading
    var errorData = MutableLiveData<ErrorResult>()//错误信息


    private fun showLoading() {
        isShowLoading.value = true
    }

    private fun dismissLoading() {
        isShowLoading.value = false
    }

    private fun showError(error: ErrorResult) {
        errorData.value = error
    }


    /**
     * 请求接口，可定制是否显示loading和错误提示
     */
    fun <T> launch(
        block: suspend CoroutineScope.() -> BaseResult<T>,//请求接口方法，T表示data实体泛型，调用时可将data对应的bean传入即可
        liveData: MutableLiveData<T>,
        isShowLoading: Boolean = false,
        isShowError: Boolean = true
    ) {
        if (isShowLoading) showLoading()
        viewModelScope.launch {
            try {
//                 var result: BaseResult<T>? = null
//                 withContext(Dispatchers.IO) {
//                     result = block()
//                 }
//                 if (result!!.errorCode == 0) {//请求成功
//                     liveData.value = result!!.data
//                 } else {
//                     LogUtil.e("请求错误>>" + result!!.errorMsg)
//                     showError(ErrorResult(result!!.errorCode, result!!.errorMsg, isShowError))
//                 }
                val result = withContext(Dispatchers.IO) { block() }
                if (result.errorCode == 0) {//请求成功
                    liveData.value = result.data
                } else {
                    LogUtils.e("请求错误>>" + result.errorMsg)
                    showError(ErrorResult(result.errorCode, result.errorMsg, isShowError))
                }
            } catch (e: Throwable) {//接口请求失败
                LogUtils.e("请求异常>>" + e.message)
                val errorResult = ErrorUtil.getError(e)
                errorResult.show = isShowError
                showError(errorResult)
            } finally {//请求结束
                dismissLoading()
            }
        }
    }


    fun <T> launch(
        api: suspend CoroutineScope.() -> BaseResult<T>,
        success: CoroutineScope.(T) -> Unit
    ) {
        viewModelScope.launch {
            withContext(Dispatchers.IO) {//异步请求接口
                val result = api()
                withContext(Dispatchers.Main) {
                    result.data?.let { success(it) }
                }
            }
        }
    }


}